package com.markerhub.service;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.markerhub.common.RedisKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Random;

/**
 * @Author by MaXiaofeng
 * @Description TODO
 * @Date 2022/2/9 15:37
 * @Version 1.0.0
 */
@Component
public class WxService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static String openId;
    /**
     * 加密数据解密算法
     * 接口如果涉及敏感数据（如wx.getUserInfo当中的 openId 和 unionId），接口的明文内容将不包含这些敏感数据。
     * 开发者如需要获取敏感数据，需要对接口返回的加密数据(encryptedData) 进行对称解密
     *
     * @param encryptedData
     * @param sessionId
     * @param vi
     * @return
     * @throws Exception
     */
    public String wxDecrypt(String encryptedData, String sessionId, String vi) throws Exception {
        // 开始解密
        String json = redisTemplate.opsForValue().get(RedisKey.WX_SESSION_ID + sessionId).replace("\\", "");
        json = json.substring(1,json.length()-1);
        System.out.println(json);
        JSONObject jsonObject = JSON.parseObject(json);
        String sessionKey = (String) jsonObject.get("session_key");
        openId = (String) jsonObject.get("openid");
        byte[] encData = cn.hutool.core.codec.Base64.decode(encryptedData);
        byte[] iv = cn.hutool.core.codec.Base64.decode(vi);
        byte[] key = Base64.decode(sessionKey);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        return new String(cipher.doFinal(encData), "UTF-8");
    }

    /**
     * 生成随机用户名，数字和字母组成,
     *
     * @param length
     * @return
     */
    public String getStringRandom(int length) {
        StringBuilder val = new StringBuilder();
        Random random = new Random();
        //参数length，表示生成几位随机数
        for (int i = 0; i < length; i++) {
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            //输出字母还是数字
            if ("char".equalsIgnoreCase(charOrNum)) {
                //输出是大写字母还是小写字母
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val.append((char) (random.nextInt(26) + temp));
            } else {
                val.append(random.nextInt(10));
            }
        }
        return val.toString();
    }
    public static String getOpenId(){
        return openId;
    }
}
